package com.dboper.search.observer;

import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.dboper.search.exception.monitor.MonitorModuleException;
import com.dboper.search.sqlparams.util.Assert;

public class ObserverModule{
	
	private ObserverModule(){};
	
	private static class ObserverModuleHolder{
    	public static ObserverModule instance=new ObserverModule();
	}
	
	public static ObserverModule getInstance(){
		return ObserverModuleHolder.instance;
	}
	
	private static final Logger logger = LoggerFactory.getLogger(ObserverModule.class);

	private ConcurrentHashMap<String,ObserverItem> observerItems=new ConcurrentHashMap<String, ObserverItem>();
	private ConcurrentHashMap<String,FileAlterationMonitor> monitors=new ConcurrentHashMap<String,FileAlterationMonitor>();
	private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
	
	public void addObserverItem(ObserverItem observerItem){
		if(observerItem!=null){
			String observerItemName=observerItem.getName();
			observerItems.put(observerItemName,observerItem);
			try {
				Resource[] resources = resolver.getResources("classpath*:"+observerItem.getDir()+"/*."+observerItem.getSuffix());  
				if(resources!=null && resources.length>0){
					String dir=resources[0].getFile().getParentFile().getAbsolutePath();
					FileAlterationObserver observer=new FileAlterationObserver(dir,FileFilterUtils.suffixFileFilter("."+observerItem.getSuffix()));
					for(FileAlterationListener listener:observerItem.getListeners()){
						observer.addListener(listener);
					}
					FileAlterationMonitor monitor=new FileAlterationMonitor(observerItem.getInterval(),observer);
					monitors.put(observerItemName,monitor);
					monitor.start();
					logger.debug("对于{}添加监控完成，并且启动成功",observerItemName);
				}else{
					logger.debug("对于{}添加监控时没有找到相应的资源文件",observerItemName);
				}
			}catch (Exception e) {
				e.printStackTrace();
				logger.debug("对于{}添加监控时出现异常",observerItemName);
			}
		}
	}
	
	public void removeObserverItem(String observerItemName) throws Exception{
		stop(observerItemName);
		observerItems.remove(observerItemName);
	}
	
	public void start(String monitorName) throws Exception{
		FileAlterationMonitor monitor=monitors.get(monitorName);
		Assert.notNull(monitor,new MonitorModuleException("monitorName为"+monitorName+"的monitor不存在"));
		monitor.start();
	}
	
	public void stop(String monitorName) throws Exception{
		FileAlterationMonitor monitor=monitors.get(monitorName);
		Assert.notNull(monitor,new MonitorModuleException("monitorName为"+monitorName+"的monitor不存在"));
		monitor.stop();
	}
	
	public void stopAllMonitor() throws Exception{
		for(String monitorName:monitors.keySet()){
			stop(monitorName);
		}
	}
}
